package icu.qrcode.msg5g.chatbot.qrcodeicuSdk;

import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.*;

public class QrcodeicuDataTableExecutor {
    private QrcodeicuSdk sdk;

    private String dataTableId;

    private String colLabel;

    private String value;

    public QrcodeicuDataTableExecutor(QrcodeicuSdk sdk, String dataTableId) {
        this.sdk = sdk;
        this.dataTableId = dataTableId;
    }

    public QrcodeicuDataTableExecutor whereEq(String colLabel, String value) {
        this.colLabel = colLabel;
        this.value = value;
        return this;
    }

    public Map<String, Object> fetchOne() {
        String accessToken = this.sdk.getAccessToken();
        if (accessToken == null) {
            return null;
        }

        String api = "/dataTables/" + this.dataTableId + "/content/records/qOne";
        String searchParam = null;
        if (this.colLabel != null) {
            searchParam = "{\"searchFilters\":[{\"label\":\"" + this.colLabel +
                    "\",\"content\":\"" + this.value + "\",\"condition\":4}],\"searchSorts\":[]}";
        }

        String result = HttpUtil.createPost(this.sdk.endpoint + api)
                .header("Authorization", "Bearer " + accessToken)
                .body(searchParam)
                .execute()
                .body();

        try {
            Map<String, Object> ret = new Gson().fromJson(result, new com.google.gson.reflect.TypeToken<HashMap<String, Object>>() {
            }.getType());
            return ret;
        } catch (Exception e) {

        }
        return null;
    }

    public Integer fetchCount() {
        String accessToken = this.sdk.getAccessToken();
        if (accessToken == null) {
            return null;
        }

        String api = "/dataTables/" + this.dataTableId + "/content/recordsCount";
        String searchParam = null;
        if (this.colLabel != null) {
            searchParam = "{\"searchFilters\":[{\"label\":\"" + this.colLabel +
                    "\",\"content\":\"" + this.value + "\",\"condition\":4}],\"searchSorts\":[]}";
        }

        String result = HttpUtil.createPost(this.sdk.endpoint + api)
                .header("Authorization", "Bearer " + accessToken)
                .body(searchParam)
                .execute()
                .body();

        try {
            CountResult r = (new Gson()).fromJson(result, CountResult.class);
            return r.count;
        } catch (Exception e) {

        }
        return null;
    }

    public String createData(Map<String, Object> param) {
        String accessToken = this.sdk.getAccessToken();
        if (accessToken == null) {
            return null;
        }

        List<AddAction> addActions = new ArrayList<>();
        String rId = "new-" + UUID.randomUUID().toString();
        param.forEach((key, value) -> {
            addActions.add(new AddAction("UpdateCell", rId, key, value));
        });

        String api = "/dataTables/" + this.dataTableId + "/records";
        String result = HttpUtil.createRequest(Method.PUT, this.sdk.endpoint + api)
                .header("Authorization", "Bearer " + accessToken)
                .body((new Gson()).toJson(addActions))
                .execute()
                .body();

        try {
            List<AddResult> ret = (new Gson()).fromJson(result, new TypeToken<ArrayList<AddResult>>() {
            }.getType());
            if (ret.size() == 0) {
                return null;
            }

            return ret.get(0).recordId;
        } catch (Exception e) {

        }
        return null;
    }

    public String createFormEditUrl(String recordId) {
        String accessToken = this.sdk.getAccessToken();
        if (accessToken == null) {
            return null;
        }

        String api = "/dataTables/" + this.dataTableId + "/" + recordId + "/formEditUrl";
        String result = HttpUtil.createGet(this.sdk.endpoint + api)
                .header("Authorization", "Bearer " + accessToken)
                .execute()
                .body();

        try {
            FormEditUrl r = (new Gson()).fromJson(result, FormEditUrl.class);
            return r.url;
        } catch (Exception e) {

        }
        return null;
    }
}

class CountResult {
    public Integer count;
}

class FormEditUrl{
    public String url;
}

class AddResult {
    public String recordId;
}

class AddAction {
    public String action;
    public String recordId;
    public String label;
    public Object value;

    public AddAction(String action, String recordId, String label, Object value) {
        this.action = action;
        this.recordId = recordId;
        this.label = label;
        this.value = value;
    }
}